package com.srwl.mytx.activity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.fastjson.JSONObject;
import com.google.android.material.appbar.AppBarLayout;
import com.srwl.easeui.widget.MyTitleBar;
import com.srwl.mytx.Constant;
import com.srwl.mytx.Helper;
import com.srwl.mytx.MyApplication;
import com.srwl.mytx.domain.User;
import com.srwl.mytx.R;
import com.srwl.mytx.RetrofitManager;
import com.srwl.mytx.adapter.AdvertisementRecordAdapter;
import com.srwl.mytx.domain.Advertisement;
import com.srwl.mytx.domain.CommonResult;
import com.srwl.mytx.domain.LiveRoom;
import com.srwl.mytx.parse.UserProfileManager;
import com.srwl.mytx.service.AdvertisementService;
import com.srwl.mytx.utils.MoneyInputCheck;
import com.srwl.mytx.utils.PayUtils;
import com.srwl.mytx.utils.Utils;
import com.srwl.mytx.widget.ConfirmDialog;
import com.srwl.mytx.widget.NodataFooter;
import com.srwl.mytx.widget.TimeSelectorView;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import me.dkzwm.widget.srl.MaterialSmoothRefreshLayout;
import me.dkzwm.widget.srl.SmoothRefreshLayout;
import me.dkzwm.widget.srl.extra.footer.MaterialFooter;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class PutAdvertisementActivity extends BaseActivity {
    private static final String TAG = "AdvertisementActivity";
    public static final int REQUEST_CODE_TO_SET_ADVERTISEMENT_ACTIVITY = 1;
    @BindView(R.id.app_bar)
    AppBarLayout appBarLayout;
    @BindView(R.id.tv_live_room_title)
    TextView tv_liveRoomTitle;

    @BindView(R.id.refresh_layout)
    MaterialSmoothRefreshLayout refreshLayout;
    @BindView(R.id.rv_offer)
    RecyclerView rv_offer;
    @BindView(R.id.progress_bar)
    ProgressBar progressBar;
    @BindView(R.id.et_offer_amount)
    EditText et_offerAmount;
    @BindView(R.id.et_deposit)
    EditText et_deposit;
    @BindView(R.id.btn_offer)
    Button btn_offer;
    @BindView(R.id.tv_starting_date)
    TextView tv_startDate;
    @BindView(R.id.time_selector)
    TimeSelectorView time_selector;
    @BindView(R.id.title_bar)
    MyTitleBar titleBar;
    private PopupWindow mPopupWindow;
    private View mPopupView;
    public TextView mTvPopupMsg;
    private boolean amountInputRight;

    private List<Advertisement> advertisementList = new ArrayList<>();
    private AdvertisementRecordAdapter advertisementRecordAdapter;
    private LiveRoom liveRoom;
    private int page = 1;
    private int size = 10;
    private boolean hasNextPage;
    private MoneyInputCheck offerInputCheck;//单价输入检测
    private MoneyInputCheck depositInputCheck;//保证金输入检测
    private Advertisement historyAdvertisement;
    private Double deposit;
    private BigDecimal offerAmount;
    //服务端返回的24小时的历史最高价记录
    private Map<Integer, Object> maxPriceRecord;
    private LocalBroadcastManager broadcastManager;
    private BroadcastReceiver receiver;
    //投放时段
    private List<Integer> timeList = new ArrayList<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_put_advertisement);
        ButterKnife.bind(this);
        liveRoom = getIntent().getParcelableExtra("liveRoom");
        tv_liveRoomTitle.setText(liveRoom.getTitle());
        rv_offer.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
        advertisementRecordAdapter = new AdvertisementRecordAdapter(this, advertisementList);
        rv_offer.setAdapter(advertisementRecordAdapter);
        loadData(true, false);
        initTextChangedListener();
        initRefreshLayout();
        time_selector.setOnChangeTimeListener(new TimeSelectorView.OnChangeTimeListener() {
            @Override
            public void onChangeTime(boolean isSelect, List<Integer> seletedList) {
                if (seletedList.size() == 0) {
                    tv_startDate.setText("");
                } else {
                    tv_startDate.setText(seletedList.toString());
                }
                timeList = seletedList;
                computeDeposit();
            }

            @Override
            public void onScrollStateChange(boolean scrolling) {
                //当时段选择View 处于滑动中，禁用 下拉刷新和加载
                refreshLayout.setDisableRefresh(scrolling);
                refreshLayout.setDisableLoadMore(scrolling);
            }
        });
        titleBar.setRightLayoutClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ConfirmDialog dialog = new ConfirmDialog(PutAdvertisementActivity.this, "说明", "广告位以小时为单位计价，出价后可设置视频、图片等作为广告展示内容，还可以设置广告位点击跳转的个人发布信息或者外部链接，如果竞价成功，聊天室在对应的广告投放时段会展示您设置的内容");
                dialog.show();
            }
        });
        initBroadCastListener();
        initPopupWindow();
    }


    private void initRefreshLayout() {
        refreshLayout.setDisableRefresh(false);
        refreshLayout.setDisableLoadMore(true);
        refreshLayout.setEnableOverScroll(false);
        refreshLayout.setOnRefreshListener(new SmoothRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefreshing() {
                refreshData();
            }

            @Override
            public void onLoadingMore() {
                if (hasNextPage) {
                    loadData(false, false);
                } else {
                    refreshLayout.refreshComplete();
                }
            }

        });
    }

    private void refreshData() {
        page = 1;
        offerInputCheck.setMoreThan(null);
        refreshLayout.postDelayed(() -> refreshLayout.setFooterView(new MaterialFooter(PutAdvertisementActivity.this)), 2000);
        loadData(false, true);
    }

    private void loadData(boolean isFirst, boolean isRefresh) {
        if (!Helper.getInstance().isNetworkConnected()) {
            showToast_v1(getString(R.string.network_anomalies));
            return;
        }
        Map<String, Object> info = new HashMap<>();
        info.put("page", page);
        info.put("size", size);
//        info.put("startDate", startDate);
//        info.put("endDate", endDate);
        info.put("liveRoomId", liveRoom.getId());
        if (isFirst) {
            progressBar.setVisibility(View.VISIBLE);
        }
        RetrofitManager.getInstance().createRequest(AdvertisementService.class)
                .queryAdvertisement_v1(info)
                .enqueue(new Callback<CommonResult>() {
                    @Override
                    public void onResponse(Call<CommonResult> call, Response<CommonResult> response) {
                        if (isFirst) {
                            progressBar.setVisibility(View.GONE);
                        } else {
                            refreshLayout.refreshComplete();
                        }
                        CommonResult result = response.body();
                        if (!response.isSuccessful() || result == null) {
                            Log.e(TAG, "onResponse: " + response.message());
                            return;
                        }
                        if (result.isError()) {
                            Log.e(TAG, "onResponse: " + result.getMsg());
                            return;
                        }
                        JSONObject resultData = (JSONObject) result.getData();
                        Log.d(TAG, "onResponse: 获取出价信息完成" + resultData.toJSONString());
                        if (page == 1) {
                            if (maxPriceRecord == null) {
                                maxPriceRecord = new HashMap<>();
                            } else {
                                maxPriceRecord.clear();
                            }
                            if (resultData.containsKey("maxPriceRecord")) {
                                JSONObject maxPriceRecordObject = resultData.getJSONObject("maxPriceRecord");
                                Set<Map.Entry<String, Object>> entries = maxPriceRecordObject.entrySet();
                                //后端传回来的key 是String,转化为Integer
                                for (Map.Entry<String, Object> entry : entries) {
                                    String key = entry.getKey();
                                    maxPriceRecord.put(Integer.valueOf(key), entry.getValue());
                                }
                            }
                            time_selector.setMaxPriceRecord(maxPriceRecord);
                        }
                        JSONObject pageInfo = resultData.getJSONObject("pageInfo");
                        List<Advertisement> advertisements = pageInfo.getJSONArray("list").toJavaList(Advertisement.class);
                        hasNextPage = pageInfo.getBoolean("hasNextPage");
                        //如果没有出价记录，会显示暂无数据， 不用显示 footer
                        if (advertisements.size() != 0 && !hasNextPage) {
                            refreshLayout.postDelayed(() -> refreshLayout.setFooterView(new NodataFooter(PutAdvertisementActivity.this)), 2000);
                        }
                        if (isRefresh) {
                            advertisementList.clear();
                        }
                        for (Advertisement advertisement : advertisements) {
                            advertisement.setLiveRoom(liveRoom);
                        }
                        advertisementList.addAll(advertisements);
                        advertisementRecordAdapter.notifyDataSetChanged();
                        page++;
                    }

                    @Override
                    public void onFailure(Call<CommonResult> call, Throwable t) {
                        if (isFirst) {
                            progressBar.setVisibility(View.GONE);
                        } else {
                            refreshLayout.refreshComplete();
                        }
                        Log.e(TAG, "onFailure: " + t.getMessage());
                    }
                });
    }


    private void initTextChangedListener() {

        offerInputCheck = new MoneyInputCheck(this, new MoneyInputCheck.InteractionListener() {
            @Override
            public void showErrorMessage(String message) {
                // et_offerAmount.setError(message);
                showPopupWindow(appBarLayout, mTvPopupMsg, message);
                //btn_offer.setEnabled(false);
                amountInputRight = false;
            }

            @Override
            public void waitInput() {
                hidePopupWindow();
                //btn_offer.setEnabled(false);
                amountInputRight = false;
                et_deposit.setEnabled(false);
                // time_selector.resetBackground();
            }

            @Override
            public void inputRight() {
//                if (!isAuctionEnd) {
//                    btn_offer.setEnabled(true);
//                }
                amountInputRight = true;
                hidePopupWindow();
                offerAmount = new BigDecimal(et_offerAmount.getText().toString().trim());
                computeDeposit();
                et_deposit.setEnabled(true);
                //  time_selector.generateMaxRecord(offerAmount);
            }
        });
        //0.1元是单位小时的默认最低价格
        offerInputCheck.setMinLimit(0.1);
        et_offerAmount.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                offerInputCheck.onTextChanged(s);
            }

            @Override
            public void afterTextChanged(Editable s) {
                offerInputCheck.afterTextChanged(s);
            }
        });


        depositInputCheck = new MoneyInputCheck(this, new MoneyInputCheck.InteractionListener() {
            @Override
            public void showErrorMessage(String message) {
                showPopupWindow(appBarLayout, mTvPopupMsg, message);
            }

            @Override
            public void waitInput() {
                hidePopupWindow();
            }

            @Override
            public void inputRight() {
                hidePopupWindow();
                deposit = Double.valueOf(et_deposit.getText().toString().trim());
            }
        });

        et_deposit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                depositInputCheck.onTextChanged(s);
            }

            @Override
            public void afterTextChanged(Editable s) {
                depositInputCheck.afterTextChanged(s);
            }
        });
    }


    @OnClick(R.id.btn_offer)
    public void offer() {
        hideSoftKeyboard();
        if (Utils.isTempUser(UserProfileManager.getInstance().getLoginUserInfo())) {
            startActivity(new Intent(PutAdvertisementActivity.this, LoginActivity.class).putExtra("EXTRA_CONTENT", "广告位投放需要登录"));
            return;
        }
        if (timeList == null || timeList.size() == 0) {
            showToast(btn_offer, "广告位投放的时间段没有选择");
            return;
        }

        if (!amountInputRight) {
            showToast(btn_offer, "金额输入有误");
            return;
        }

        offerAmount = new BigDecimal(et_offerAmount.getText().toString().trim());
        String tips = "投放竞价广告位，将产生保证金";
        //判断支付金额是否超过用户设置的免密码支付的金额
        if (deposit <= UserProfileManager.getInstance().getPayLimit()) {
            //弹出提示框，提示用户是否确认生成等额保证金
            ConfirmDialog dialog = new ConfirmDialog(this, "确定", tips + ": ¥" + deposit, true);
            dialog.setConfirmListener(() -> {
                new PayUtils(PutAdvertisementActivity.this, deposit, tips, payPassword -> doOffer(offerAmount.doubleValue(), payPassword));//直接调用支付工具，如果保证金金额小于免密支付额度，将不会弹出支付对话框
            });
            dialog.show();
        } else {
            new PayUtils(PutAdvertisementActivity.this, deposit, tips, payPassword -> doOffer(offerAmount.doubleValue(), payPassword));//直接调用支付工具，如果保证金金额小于免密支付额度，将不会弹出支付对话框
        }

        
        /*PayPasswordDialog payPasswordDialog = new PayPasswordDialog(PutAdvertisementActivity.this, tips, deposit);
        payPasswordDialog.setOnConfirmListener(new PayPasswordDialog.OnConfirmListener() {
            @Override
            public void onCommit(String passWord) {
                doOffer(offerAmount.doubleValue(), passWord);
            }
        });
        payPasswordDialog.show();*/
    }

    /**
     * 投放广告
     *
     * @param offerAmount
     * @param payPassword
     */
    private void doOffer(Double offerAmount, String payPassword) {
        if (!Helper.getInstance().isNetworkConnected()) {
            showToast_v1(getString(R.string.network_anomalies));
            return;
        }
        Advertisement advertisement = new Advertisement();
        advertisement.setrId(liveRoom.getId());
        advertisement.setAmount(offerAmount);
        advertisement.setTime(timeList);
        advertisement.setTitle(liveRoom.getTitle());
        advertisement.setStatus(Constant.ADVERTISEMENT_STATUS_NORMAL);  //如果不设置其状态，在当前活动中出价完成后直接点击其生成的item会报空指针异常
        //根据单价和投放的时长，计算出保证金
        computeDeposit();
        advertisement.setDeposit(deposit);
        Map<String, Object> body = new HashMap<>();
        if (payPassword != null) {
            body.put("payPassword", payPassword);
        }
        body.put("advertisement", advertisement);
        progressBar.setVisibility(View.VISIBLE);
        RetrofitManager.getInstance().createRequest(AdvertisementService.class)
                .putAdvertisement(body)
                .enqueue(new Callback<CommonResult>() {
                    @Override
                    public void onResponse(Call<CommonResult> call, Response<CommonResult> response) {
                        progressBar.setVisibility(View.INVISIBLE);
                        CommonResult result = response.body();
                        if (!response.isSuccessful() || result == null) {
                            Log.e(TAG, "onResponse: " + response.message());
                            showToast(btn_offer, getString(R.string.system_busy));
                            return;
                        }

                        if (result.isError()) {
                            switch (result.getStatus()) {
                                case Constant.PAY_PASSWORD_ERROR:
                                    showToast(btn_offer, getString(R.string.pay_password_error));
                                    break;
                                case Constant.UNKNOWN_ERROR:
                                    showToast(btn_offer, getString(R.string.system_busy));
                                    break;
                                case Constant.BALANCE_NOT_ENOUGH:
                                    showToast(btn_offer, getString(R.string.balance_not_enough));
                                    break;
                                case Constant.PARAMETER_INVALID:
                                    showToast(btn_offer, result.getMsg());
                                    break;
                                case Constant.OFFER_BUSY:
                                    showToast(btn_offer, getString(R.string.system_busy));
                                    break;
                                default:
                                    showToast(btn_offer, getString(R.string.system_busy));
                            }
                            Log.e(TAG, "onResponse: " + result.getMsg());
                            return;
                        }

                        Log.d(TAG, "onResponse: 出价完成");
                        // time_selector.refreshMaxPriceRecord(BigDecimal.valueOf(offerAmount));
                        // time_selector.generateGreyOfferRecordView();
                        // btn_offer.setEnabled(false);
                        //et_offerAmount.setText("");
                        offerInputCheck.setMoreThan(offerAmount);
                        //返回账户保证金总额。出价并不会对账户余额做操作，只是增加保证金的金额，任何支出都应该减去保证金后做判断是否足够
                        JSONObject jsonObject = (JSONObject) result.getData();
                        if (jsonObject.containsKey("deposit")) {
                            Double deposit = jsonObject.getDouble("deposit");
                            UserProfileManager.getInstance().setDeposit(deposit);
                        }
                        if (jsonObject.containsKey("advertisementId")) {
                            String advertisementId = jsonObject.getString("advertisementId");
                            advertisement.setId(advertisementId);
                        }
                        User loginUserInfo = UserProfileManager.getInstance().getLoginUserInfo();
                        advertisement.setuId(UserProfileManager.getInstance().getLoginUserInfo().getuId());
                        advertisement.setLiveRoom(liveRoom);
                        advertisement.setCreated(new Date(System.currentTimeMillis() + MyApplication.timeOffset));

                        ConfirmDialog dialog = new ConfirmDialog(PutAdvertisementActivity.this, "提示", "出价完成，去设置广告展示内容?", true);
                        dialog.setConfirmListener(new ConfirmDialog.ConfirmListener() {
                            @Override
                            public void confirm() {
                                //startActivityForResult(new Intent(PutAdvertisementActivity.this, SetAdvertisementContentActivity.class).putExtra("advertisement", advertisement), REQUEST_CODE_TO_SET_ADVERTISEMENT_ACTIVITY);
                                SetAdvertisementContentActivity.startActivity(PutAdvertisementActivity.this, advertisement, REQUEST_CODE_TO_SET_ADVERTISEMENT_ACTIVITY);
                            }
                        });
                        dialog.show();

                        refreshAdvertisementRecordList(loginUserInfo, advertisement);

                    }

                    @Override
                    public void onFailure(Call<CommonResult> call, Throwable t) {
                        Log.e(TAG, "onFailure: " + t.getMessage());
                        progressBar.setVisibility(View.INVISIBLE);
                    }
                });
    }

    private void refreshAdvertisementRecordList(User loginUserInfo, Advertisement advertisement) {
        if (advertisementList.size() == 0) {
            advertisementList.add(advertisement);
            advertisementRecordAdapter.notifyDataSetChanged();
        } else {
            advertisementList.add(0, advertisement);
            advertisementRecordAdapter.notifyItemInserted(0);
        }
    }

    /**
     * 计算保证金 最低限额
     */
    private void computeDeposit() {
        if (offerAmount == null || timeList.size() == 0) {
            return;
        }
        BigDecimal tempDeposit = offerAmount.multiply(new BigDecimal(timeList.size()));
//        if (deposit == null || tempDeposit.compareTo(new BigDecimal(deposit)) > 0) {
//        }
        deposit = tempDeposit.doubleValue();
        depositInputCheck.setMinLimit(deposit);
        et_deposit.setText(Utils.moneyFormat(deposit));
        Log.i(TAG, "doOffer: 保证金" + deposit);
    }


    protected void initBroadCastListener() {

        broadcastManager = LocalBroadcastManager.getInstance(this);
        IntentFilter filter = new IntentFilter();
        filter.addAction(Constant.ACTION_ON_LIVE_ROOM_ADVERTISEMENT_PRICE_CHANGE);
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (Constant.ACTION_ON_LIVE_ROOM_ADVERTISEMENT_PRICE_CHANGE.equals(intent.getAction())) {
                    Log.d(TAG, "onReceive: 收到广告出价信息改变通知");
                    refreshData();
                }
            }
        };
        broadcastManager.registerReceiver(receiver, filter);

    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode != RESULT_OK) {
            return;
        }

        if (requestCode == REQUEST_CODE_TO_SET_ADVERTISEMENT_ACTIVITY) {

            Advertisement updatedAdvertisement = data.getParcelableExtra("advertisement");
            if (updatedAdvertisement == null) return;

            for (int i = 0; i < advertisementList.size(); i++) {
                Advertisement advertisement = advertisementList.get(i);
                if (TextUtils.equals(advertisement.getId(), updatedAdvertisement.getId())) {
                    advertisementList.remove(i);
                    advertisementList.add(i, updatedAdvertisement);
                    advertisementRecordAdapter.notifyItemChanged(i);
                    break;
                }
            }


        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        broadcastManager.unregisterReceiver(receiver);
    }

    public void initPopupWindow() {
        if (mPopupView == null) {
            mPopupView = getLayoutInflater().inflate(R.layout.rp_popup_layout, null, false);
        }
        if (mPopupWindow == null) {
            mPopupWindow = new PopupWindow(mPopupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            mTvPopupMsg = (TextView) mPopupView.findViewById(R.id.tv_popup_msg);
            mPopupWindow.setOutsideTouchable(false);
        }
    }


    public void showPopupWindow(View parentView, TextView tvPopupMsg, String message) {
        tvPopupMsg.setText(message);
        int[] location = new int[2];
        parentView.getLocationOnScreen(location);
        int offsetY = location[1] + parentView.getHeight();
        if (mPopupWindow != null && !mPopupWindow.isShowing()) {
            mPopupWindow.showAtLocation(parentView, Gravity.START | Gravity.TOP, 0, offsetY);
        }
    }

    public void hidePopupWindow() {
        if (mPopupWindow != null && mPopupWindow.isShowing()) {
            mPopupWindow.dismiss();
        }
    }

    @Override
    protected void onAccountChange() {
        super.onAccountChange();
        refreshData();

    }
}
